package com.lengxf.pay.common.http;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.*;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.lengxf.pay.common.PayException;
import com.lengxf.pay.common.bean.Param;
import com.lengxf.pay.common.config.TransactionType;

public class PayRequestTemplate {

    private static final Log log = LogFactory.get();

    private final HttpConfig httpConfig;

    public PayRequestTemplate(HttpConfig httpConfig) {
        Assert.notNull(httpConfig);
        this.httpConfig = httpConfig;
    }

    public <T, P extends Param> T execute(HttpParam<P> param, Class<T> clazz) {
        TransactionType transactionType = param.getTransactionType();
        Method method = transactionType.method();
        String result = switch (method) {
            case GET -> doGet(param);
            case POST -> doPost(param);
            default -> throw new UnsupportedOperationException(String.format("不支持{%s}请求方法", method));
        };
        return JSONUtil.toBean(result, clazz);
    }

    private <P extends Param> String doPost(HttpParam<P> param) {
        return switch (param.getContentType()) {
            case JSON -> doJsonPost(param);
            case XML -> doXmlPost(param);
            default -> doFormPost(param);
        };
    }

    private <P extends Param> String doXmlPost(HttpParam<P> param) {
        return execute(HttpUtil.createPost(param.requestUrl())
                .setConfig(httpConfig)
                .addHeaders(param.getHeaderMap())
                .body(param.getParam().toXml()));
    }

    private <P extends Param> String doJsonPost(HttpParam<P> param) {
        return execute(HttpUtil.createPost(param.requestUrl())
                .setConfig(httpConfig)
                .addHeaders(param.getHeaderMap())
                .body(param.getParam().toJson()));
    }

    private <P extends Param> String doFormPost(HttpParam<P> param) {
        return execute(HttpUtil.createPost(param.requestUrl())
                .setConfig(httpConfig)
                .addHeaders(param.getHeaderMap())
                .form(param.getParam().toMap()));
    }


    private <P extends Param> String doGet(HttpParam<P> param) {
        String fullUrl = appendQueryParams(param.requestUrl(), param.getParam().toKvStr());
        return execute(HttpUtil.createGet(fullUrl)
                .setConfig(httpConfig)
                .addHeaders(param.getHeaderMap()));
    }

    private String appendQueryParams(String url, String params) {
        return StrUtil.isBlank(params) ? url : url + "?" + params;
    }

    private static String execute(HttpRequest httpRequest) {
        try (HttpResponse execute = httpRequest.execute()) {
            return execute.body();
        } catch (Exception e) {
            log.error("请求接口 {} 异常 : {}", httpRequest.getUrl(), e);
            throw new PayException(String.format("请求服务异常,接口为: { %s }", httpRequest.getUrl()));
        }
    }


}
